/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 
*   Copyright 2014 Jan-Marwin Wollschläger                                   *
*                                                                            *
*   Licensed under the Apache License, Version 2.0 (the "License");          *
*   you may not use this file except in compliance with the License.         *
*   You may obtain a copy of the License at                                  *
*                                                                            *
*       http://www.apache.org/licenses/LICENSE-2.0                           *
*                                                                            *
*   Unless required by applicable law or agreed to in writing, software      *
*   distributed under the License is distributed on an "AS IS" BASIS,        *
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
*   See the License for the specific language governing permissions and      *
*   limitations under the License.                                           *
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **  */ 

import java.math.*;

/**
 * The two-dimensional Vector class that will be used throughout
 * this application.
 *
 * @author Jan-Marwin Wollschläger
 * @version 0.1
 **/
public class Vector2 implements IVector2
{
  private final static float EQUALS_THRESHOLD = 0.00001f;
  
  private float x;
  private float y;
  
  
  public Vector2(float X, float Y)
  {
    x = X; y = Y;
  }
  
  /**
   * @param obj The object to check equality with.
   * @return Returns True if obj is equal to this instance, where equal means
   * that the float data members x and y of obj only differ at about the fifth
   * decimal place. 
   **/
  public boolean equals(Object obj)
  {
    try{
      final IVector2 asVec = (IVector2) obj;
      return (_abs(asVec.getX() - x) < EQUALS_THRESHOLD) && (_abs(asVec.getY() - y) < EQUALS_THRESHOLD);
    }catch(Exception e)
    {
       return false; 
    }
  }
 
   /**
   * @return Returns the x coordinate of this Vector2 instance.
   **/
  public float getX(){return x;}
  
   /**
   * @return Returns the y coordinate of this Vector2 instance.
   **/
  public float getY(){return y;}
  
   /**
   * Sets the x coordinate of this Vector2 instance.
   * @param X The new x coordinate.
   **/
  public void setX(float X){x=X;}
  
   /**
   * Sets the y coordinate of this Vector2 instance.
   * @param Y The new y coordinate.
   **/
  public void setY(float Y){y=Y;} 
  
  /**
   * Returns this instance plus amountToSubtract:
   * 	this (+) amountToSubtract,   
   * where (+) means componentwise addition.
   * @return The vector as IVector2 instance after applying
   * componentwise addition as described above.
   **/
   public IVector2 vecPlus(IVector2 toAdd)
   {
	   return new Vector2(x+toAdd.getX(), y+toAdd.getY());
   }
   
   
   /**
   * Returns this instance minus amountToSubtract:
   * 	this (-) amountToSubtract,   
   * where (-) means componentwise subtraction.
   * @return The vector as IVector2 instance after applying
   * componentwise subtraction as described above.
   **/
   public IVector2 vecMinus(IVector2 amountToSubtract)
   {
	   return new Vector2(x-amountToSubtract.getX(),
							y-amountToSubtract.getY());
   }
   
   
   /**
   * @param scalar The scalar to multiply by.
   *  
   * @return The vector multiplied via the specified scalar.
   **/
   public IVector2 mult(float scalar)
   {
	   return new Vector2(x * scalar, y * scalar);
   }
   
   
   /**
   * @return The length of this vector.
   **/
   public float getLen()
   {
	   return (float)Math.sqrt(x*x + y*y);
   }
   
   
   /**
   * @return The squared length of this vector.
   **/
   public float getLenSquared()
   {
	   return x*x + y*y;
   }
   
  
   /**
   * Returns a vector that is orthogonal to the direction of
   * this instance.
   * @return Given an instance of IVector (x, y), this method
   * returns the orthogonal vector (y, -x).
   **/
   public IVector2 getOrthogonal(){
	    /*
	     * Return the vector (y, -x), as 
	     * (x, y) * (y, -x) = x*y - y*x = 0 
	    */
		return new Vector2(y, -x);
   }
   
   
   /**
   * Returns the distance to the other vector as a float.
   * @param otherVec The vector to measure the distance to.
   * @return The distance of this distance to otherVec as a float. 
   **/
   public float dist(IVector2 otherVec)
   {
	   return vecMinus(otherVec).getLen();
   }
   
   
   public String toString()
   {
	   return "("+x+", "+y+")";
   }
   
   public IVector2 absVec()
   {
	   
	   final float _x;
	   if(x < 0)
			_x = -x;
	   else
			_x = x;
			
	   final float _y;
	   if(y < 0)
			_y = -y;
	   else
			_y = y;
			
	   return new Vector2(_x, _y);
   }
   
  
  private static float _abs(float num){if(num < 0) return -num; else return num;}
}
